package com.eastfair.venueservice.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.auth.api.UserAccountServiceFeign;
import com.eastfair.auth.dto.UserAccountDto;
import com.eastfair.auth.vo.UserAccountVo;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.base.entity.SuperEntity;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.venueservice.consts.CommonConstants;
import com.eastfair.venueservice.dao.ServicePriceListMapper;
import com.eastfair.venueservice.dto.ServicePriceListDTO;
import com.eastfair.venueservice.dto.ServicePriceListQuery;
import com.eastfair.venueservice.entity.*;
import com.eastfair.venueservice.exceptioncode.VenueServiceExceptionCode;
import com.eastfair.venueservice.service.ExhibitionManageService;
import com.eastfair.venueservice.service.ServicePriceListDetailService;
import com.eastfair.venueservice.service.ServicePriceListItemService;
import com.eastfair.venueservice.service.ServicePriceListService;
import com.eastfair.venueservice.vo.ServicePriceListVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 价目表
 * </p>
 *
 * @author linan
 * @date 2022-07-21
 */
@Slf4j
@Service
public class ServicePriceListServiceImpl extends SuperServiceImpl<ServicePriceListMapper, ServicePriceList> implements ServicePriceListService {

    private static final String PL ="PL";
    public static final String PRICE_LIST_NO = "price_list_no";

    @Resource
    private ExhibitionManageService exhibitionManageService;
    @Resource
    private UserAccountServiceFeign userAccountServiceFeign;
    @Resource
    private ServicePriceListItemService servicePriceListItemService;
    @Resource
    private ServicePriceListDetailService servicePriceListDetailService;

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<ServicePriceList> modelList) {
        modelList.stream().forEach(s -> {
            s.setIsDeleted(BusinessConstant.YES);
        });
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(ServicePriceList model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        model.setTenantId(ContextUtil.getTenantId());
        return R.successDef();
    }

    @Override
    public R<Boolean> addPriceList(ServicePriceListDTO servicePriceList) {
        ServicePriceList priceList = BeanUtil.copyProperties(servicePriceList, ServicePriceList.class);
        priceList.setPriceListNo(CreatCode.creatCode(baseMapper, PRICE_LIST_NO, 7, PL));
        return R.success(save(priceList));
    }

    @Override
    public R<Boolean> updatePriceList(ServicePriceListDTO servicePriceList) {
        ServicePriceList priceList = BeanUtil.copyProperties(servicePriceList, ServicePriceList.class);
        return R.success(updateById(priceList));
    }

    @Override
    public void updateExhibitionNum(Long priceListId) {
        if(Objects.nonNull(priceListId)){
            QueryWrapper<ExhibitionManage> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(ExhibitionManage::getIsDeleted, BusinessConstant.NO).eq(ExhibitionManage::getPriceListId, priceListId);
            int count = exhibitionManageService.count(queryWrapper);
            this.updateById(ServicePriceList.builder().id(priceListId).exhibitionNum(count).build());
        }
    }

    @Override
    public void updateExhibitionNum(Long priceListId,int count) {
        if(Objects.nonNull(priceListId)){
            this.updateById(ServicePriceList.builder().id(priceListId).exhibitionNum(count).build());
        }
    }

    @Override
    public R<IPage<ServicePriceListVO>> queryPriceList(PageParams<ServicePriceListQuery> servicePriceListPage) {
        Page<ServicePriceList> buildPage = servicePriceListPage.buildPage();
        Page<ServicePriceListVO> result = servicePriceListPage.buildPage();
        ServicePriceListQuery model = servicePriceListPage.getModel();
        QueryWrapper<ServicePriceList> listQueryWrapper = new QueryWrapper<>();
        pageWrapper(model, listQueryWrapper);
        Page<ServicePriceList> page = page(buildPage, listQueryWrapper);
        BeanUtil.copyProperties(page, result);
        List<ServicePriceListVO> servicePriceList = new ArrayList<>();
        List<ServicePriceList> records = page.getRecords();
        List<Long> ids = records.stream().map(SuperEntity::getCreatedBy).collect(Collectors.toList());
        Map<Long, String> map = new HashMap<>(8);
        // feign接口查询用户信息
        if (CollectionUtils.isNotEmpty(ids)) {
            UserAccountDto userAccountDto = new UserAccountDto();
            userAccountDto.setUserIds(ids);
            R<List<UserAccountVo>> listR = userAccountServiceFeign.querySimpleByIds(userAccountDto);
            map = listR.getData().stream().collect(Collectors.toMap(UserAccountVo::getId, UserAccountVo::getRealName));
        }
        if(CollectionUtils.isNotEmpty(records)){
            List<Long> priceListIds = records.stream().map(SuperEntity::getId).collect(Collectors.toList());
            QueryWrapper<ExhibitionManage> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(ExhibitionManage::getIsDeleted, BusinessConstant.NO)
                    .in(ExhibitionManage::getPriceListId, priceListIds);
            List<ExhibitionManage> list = exhibitionManageService.list(queryWrapper);
            Map<Long, ExhibitionManage> exhibitionManageMap = list.stream().collect(Collectors.toMap(ExhibitionManage::getPriceListId, Function.identity()));
            for (ServicePriceList record : records) {
                ServicePriceListVO servicePriceListVO = BeanUtil.copyProperties(record, ServicePriceListVO.class);
                // 创建人名称
                servicePriceListVO.setCreatedName(map.get(record.getCreatedBy()));
                // 展会
                ExhibitionManage exhibitionManage = exhibitionManageMap.get(record.getId());
                if(Objects.nonNull(exhibitionManage)){
                    servicePriceListVO.setExhibitionManageName(exhibitionManage.getExhibitionName());
                }

                if(Objects.nonNull(model.getOnlyThisExhibition()) && model.getOnlyThisExhibition()==BusinessConstant.YES){
                    if(Objects.nonNull(exhibitionManage) && exhibitionManage.getId().equals(model.getExhibitionManageId())){
                        servicePriceList.add(servicePriceListVO);
                    }
                }else {
                    if (Objects.isNull(model.getExhibitionManageId())) {
                        // 不传展会id都查询
                        servicePriceList.add(servicePriceListVO);
                    } else if (Objects.isNull(servicePriceListVO.getExhibitionNum()) || servicePriceListVO.getExhibitionNum() == 0) {
                        // 传了展会id,返回没有帮展会的价目提供修改
                        servicePriceList.add(servicePriceListVO);
                    }else if (Objects.nonNull(exhibitionManage) && exhibitionManage.getId().equals(model.getExhibitionManageId())){
                        // 传了展会id,对应价目返回
                        servicePriceList.add(servicePriceListVO);
                    }
                }
            }
        }
        result.setRecords(servicePriceList);
        result.setTotal(page.getTotal());
        return R.success(result);
    }

    /**
     * 封装Wrapper
     * @param model
     * @param listQueryWrapper
     */
    private void pageWrapper(ServicePriceListQuery model, QueryWrapper<ServicePriceList> listQueryWrapper) {
        // 查询条件
        listQueryWrapper.lambda().eq(ServicePriceList::getIsDeleted, BusinessConstant.NO)
                .like(StringUtils.isNotBlank(model.getPriceListNo()), ServicePriceList::getPriceListNo, model.getPriceListNo())
                .like(StringUtils.isNotBlank(model.getPriceListName()), ServicePriceList::getPriceListName, model.getPriceListName())
                .ge(Objects.nonNull(model.getCreateTimeStart()), ServicePriceList::getCreateTime, model.getCreateTimeStart())
                .le(Objects.nonNull(model.getCreateTimeEnd()), ServicePriceList::getCreateTime, model.getCreateTimeEnd())
                .eq(Objects.nonNull(model.getCreatedBy()), ServicePriceList::getCreatedBy, model.getCreatedBy())
                .eq(Objects.nonNull(model.getId()), ServicePriceList::getId, model.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delPriceList(ServicePriceListDTO servicePriceList) {
        // 判断价目是否已经被展会绑定
        QueryWrapper<ExhibitionManage> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ExhibitionManage::getIsDeleted, BusinessConstant.NO).eq(ExhibitionManage::getPriceListId, servicePriceList.getId());
        List<ExhibitionManage> list = exhibitionManageService.list(queryWrapper);
        if(CollectionUtils.isNotEmpty(list) && list.get(0).getDismantlingEndTime().compareTo(LocalDateTime.now())>0){
            throw BizException.wrap(VenueServiceExceptionCode.PRICE_LIST_CANT_DELETE);
        }
        boolean b = removeByIdsOfLogic(ConvertUtil.convertList(Collections.singletonList(servicePriceList), ServicePriceList.class));
        servicePriceListItemService.update(new UpdateWrapper<ServicePriceListItem>().lambda()
                .eq(ServicePriceListItem::getIsDeleted,BusinessConstant.NO)
                .eq(ServicePriceListItem::getPriceListId,servicePriceList.getId())
                .set(ServicePriceListItem::getIsDeleted,BusinessConstant.YES));
        // 删除主场、主运服务
        servicePriceListItemService.delByServicePriceList(servicePriceList);
        return b;
    }

    @Override
    public Boolean copyPriceList(ServicePriceListDTO servicePriceList) {
        ServicePriceList priceList = getById(servicePriceList.getId());
        ServicePriceList newServicePriceList = BeanUtil.copyProperties(priceList, ServicePriceList.class, CommonConstants.COMMON_IGNORE_PROPERTIES);
        newServicePriceList.setPriceListNo(CreatCode.creatCode(baseMapper, PRICE_LIST_NO, 7, PL));
        newServicePriceList.setExhibitionNum(0);
        newServicePriceList.setPriceListName(servicePriceList.getPriceListName());
        this.save(newServicePriceList);
        // 复制服务项
        List<ServicePriceListItem> servicePriceListItems = servicePriceListItemService.list(new QueryWrapper<ServicePriceListItem>().lambda()
                .eq(ServicePriceListItem::getIsDeleted, BusinessConstant.NO)
                .eq(ServicePriceListItem::getPriceListId, servicePriceList.getId()));
        for (ServicePriceListItem servicePriceListItem : servicePriceListItems) {
            ServicePriceListItem newServicePriceListItem = BeanUtil.copyProperties(servicePriceListItem, ServicePriceListItem.class, CommonConstants.COMMON_IGNORE_PROPERTIES);
            newServicePriceListItem.setPriceListId(newServicePriceList.getId());
            servicePriceListItemService.save(newServicePriceListItem);
            // 复制明细
            List<ServicePriceListDetail> servicePriceListDetails = servicePriceListDetailService.list(new QueryWrapper<ServicePriceListDetail>().lambda()
                    .eq(ServicePriceListDetail::getIsDeleted, BusinessConstant.NO)
                    .eq(ServicePriceListDetail::getServicePriceId, servicePriceListItem.getId()));
            for (ServicePriceListDetail servicePriceListDetail : servicePriceListDetails) {
                ServicePriceListDetail newServicePriceListDetail = BeanUtil.copyProperties(servicePriceListDetail, ServicePriceListDetail.class, CommonConstants.COMMON_IGNORE_PROPERTIES);
                newServicePriceListDetail.setServicePriceId(newServicePriceListItem.getId());
                servicePriceListDetailService.save(newServicePriceListDetail);
            }
        }
        return true;
    }
}
